/**
 * react：mvc
 * vue：mvvm
 */

/**
 * <></>   <React.Fragment></React.Fragment>
 */
import PropTypes from 'prop-types';
/**
 * jsx渲染机制
 */
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <div className="box">
        <h2 className="title">我是标题</h2>
    </div>
)

/**
 * jsx语法底层的渲染机制
 * 1、基于babel-preset-react-app 语法包，可以把jsx语法，渲染解析为React.createElement 格式
 *  遇到html标签/调用组件标签，就会创建为createElement格式
 *  React.createElement(
 *    标签名/组件
 *    属性
 *    内容
 *  )
 * 2、把react.createElement方法执行，创建jsx元素对象/虚拟dom
 */

/**
 * React.Children.toArray(props.children)
 */

// 函数组件中的插槽
function Parent() {
    return (
        <div>
            <Children>
                <div slot="head">头部</div>
                <div slot="footer">尾部</div>
            </Children>
        </div>
    )
}
function Children() {
    let children = React.Children.toArray(props.children);
    let headSlots = children.filter(item => item.props.slot === 'head');
    let footlots = chidlren.filter(item => item.props.slot === 'foot');
    return (
        <div>
            {headSlots}
            子组件
            {footlots}
        </div>
    )
}
// 设置类型
Children.propTypes = {
    x: PropTypes.number.isRequired,
    y: PropTypes.string 
}
// 给组件设置默认值
Children.defaultProps = {
    num: 200
}

/**
 * 函数组件是静态组件
 *  不具备状态，生命周期，ref等内内容
 *  第一次渲染完毕，除非父组件控制其重新渲染，否则内容不会再更新
 *  优势：渲染速度快
 *  弊端：静态组件，无法实现组件动态刷新
 */

/**
 * 类组件
 *  创建一个类，并继承Reat.Component/PureComponent
 *  把类基于new执行，创造其一个实例
 *  执行过程：
 *  1、getDefaultProps && 属性规则校验
 *  2、初始化
 *      把constructor执行，把处理好的props传递给constrcutor
 *          super等价于React.Component.call(this)
 *          this.props=undefiend;this.props=undefiend;this.refs={};this.context=undefined;this.updater={...}
 *          +super(props) 此处直接把传递进来的props挂载到实例上
 *          this.props={...}
 *  3、初始化结束后，会把props/context这些信息全部挂载到实例上
 *  4、触发一个周期函数componentWillMount：第一次渲染之前
 *      不安全的周期函数。不建议使用了
 *  5、render生命周期函数
 *      把render执行返回的jsx对象进行渲染
 *  6、componentDidMount周期函数：第一次渲染完
 *      获取真实的dom元素
 *      从服务器获取数据
 *      设置定时器或监听器
 * 基于setState修改状态，通知视图更新
 *  1、触发shouldComponentUpdate：是否允许更新
 *      返回true：允许更新，继续执行后续的步骤
 *      返回false：则停止更新，
 *      可以基于这个周期函数做项目优化
 *  2、触发componentWillUpdate：不安全的
 *      进行到这一步。状态和属性还没有改为最新的值
 *  3、修改状态/属性为最新的值，基于this.props/state访问，获取的也是最新的值
 *  4、触发render
 *  5、触发componentDidUpdate：视图更新完毕
 *  6、如果setState设置了回调函数，则在视图更新完毕后，把回调函数触发执行。类似于$nextTick
 * 基于forceUpdate强制让视图更新
 *  1、直接跳过shouldComponentUpdate，继续下一步操作
 * 父组件重新调用这个组件，组件也需要更新
 *  1、触发componentWillReceiveProps：不安全
 *  2、触发shouldComponentUpdate
 *  ...
 * 组件销毁
 *  1、触发componentWillUnmount：销毁之前
 *      把自己手动设置的事件，定时器，监听器手动释放掉
 *      对目前组件中的一些信息，做缓存，（草稿箱）
 *      ...
 *  2、销毁
 * 
 */